<template>
    <div v-if="data.showBg" style="position: absolute;left: 0;top: 0;z-index: 99;width: 100%;height: 100%;"></div>
    <div style="position: absolute;left: 0;top: 0;z-index: 100;width: 100%;height: 100%;background-color: rgba(0,0,0,0.6);transition: opacity .3s cubic-bezier(0.1,0.9,0.2,1);pointer-events: none;"
        :style="{
            opacity: data.showBg ? 1 : 0
        }">
        <div style="width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;" :style="{
            transition: data.transition ? 'scale .3s cubic-bezier(0.1,0.9,0.2,1)' : '',
            scale: data.scale ? 1.1 : 1
        }">

            <flexBox v-for="pItem in (() => {
                if (data.list.length) {
                    return [data.list[data.list.length - 1]]
                }
                return []
            })()" style="pointer-events:fill;width: 100%;height: 100%;" :style="{
                zoom: status === 0 ? 1 : 1
            }">

                <div v-if="pItem.type == 'input_multipleText'"
                    style="width: calc(375px - 64px);display: inline-block;border-radius: 8px;background-color: white;">
                    <div style="width: 100%;padding: 16px 8px;text-align: center;">
                        {{ pItem.title }}
                    </div>
                    <div style="padding: 0 16px;">
                        <textarea v-model="pItem.value"
                            style="width: 100%;border: 1px solid rgb(230,230,230);border-radius: 5px;font-size: 16px;font-family: 微软雅黑;padding: 8px;outline: none;max-width: 100%;min-width: 100%;min-height: 200px;"
                            :style="{
                                maxHeight: `calc(${windowHeight / zoom}px - 48px - 48px - 64px)`
                            }" :placeholder="pItem.tip" type="text"></textarea>
                    </div>
                    <div style="width: 100%;display: flex;height: 50px;">
                        <div @click="async () => {
                            if (data.cannotClick) return
                            controls.closeTop()
                        }"
                            style="width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;color: dimgray;font-size:16px;cursor: pointer;">
                            {{ pItem.cancelText ? pItem.cancelText : '取消' }}
                        </div>
                        <div @click="async () => {
                            if (data.cannotClick) return
                            try {
                                await pItem.checkCallBack(pItem.value)
                            } catch (error) {
                                controls.toast.show({ content: `${error}`, icon: 'error', time: 3000 })
                                return
                            }
                            try {
                                await pItem.okCallBack(pItem.value)
                            } catch (error) {

                            }
                        }"
                            style="width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;color: rgb(0,120,215);font-size:16px;cursor: pointer;">
                            {{ pItem.okText ? pItem.okText : '确定' }}
                        </div>
                    </div>
                </div>

                <div v-if="pItem.type == 'input_singleText'"
                    style="width: calc(375px - 64px);display: inline-block;border-radius: 8px;background-color: white;">
                    <div style="width: 100%;padding: 16px 8px;text-align: center;">
                        {{ pItem.title }}
                    </div>
                    <div style="padding: 0 16px;">
                        <input v-model="pItem.value"
                            style="width: 100%;border: 1px solid rgb(230,230,230);border-radius: 3px;padding: 0 4px;"
                            :placeholder="pItem.tip" type="text">
                    </div>
                    <div style="width: 100%;display: flex;height: 50px;">
                        <div @click="async () => {
                            if (data.cannotClick) return
                            controls.closeTop()
                        }"
                            style="width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;color: dimgray;font-size:16px;cursor: pointer;">
                            {{ pItem.cancelText ? pItem.cancelText : '取消' }}
                        </div>
                        <div @click="async () => {
                            if (data.cannotClick) return
                            try {
                                await pItem.checkCallBack(pItem.value)
                            } catch (error) {
                                controls.toast.show({ content: `${error}`, icon: 'error', time: 3000 })
                                return
                            }
                            try {
                                await pItem.okCallBack(pItem.value)
                            } catch (error) {

                            }
                        }"
                            style="width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;color: rgb(0,120,215);font-size:16px;cursor: pointer;">
                            {{ pItem.okText ? pItem.okText : '确定' }}
                        </div>
                    </div>
                </div>

                <flexBox v-if="pItem.type == 'actionSheet'"
                    style="width: calc(375px - 64px);border-radius: 8px;background-color: white;"
                    flexDirection="column">
                    <flexBox v-if="pItem.tip"
                        style="width: 100%;height: 48px;min-height: 48px;color: #333;background-color: rgb(242,242,242);border-top: 1px solid rgb(230,230,230);">
                        {{ pItem.tip }}
                    </flexBox>
                    <div style="width: 100%;overflow-y: auto;" :style="{
                        maxHeight: `calc(${windowHeight / zoom}px - 48px - 48px - 64px)`
                    }">
                        <flexBox @click="async () => {
                            if (data.cannotClick) return
                            try {
                                await item.callBack()
                            } catch (error) {
                                console.log(error)
                            }
                        }" v-for="item in pItem.list" style="width: 100%;height: 48px;min-height: 48px;">
                            {{ item.name }}
                        </flexBox>
                    </div>
                    <flexBox @click="async () => {
                        if (data.cannotClick) return
                        controls.closeTop()
                    }"
                        style="width: 100%;height: 48px;min-height: 48px;color: #333;background-color: white;border-top: 1px solid rgb(230,230,230);">
                        取消
                    </flexBox>
                </flexBox>

                <div v-if="pItem.type == 'modal'"
                    style="width: calc(375px - 64px);display: inline-block;border-radius: 8px;background-color: white;">
                    <div
                        style="width: 100%;padding: 16px 0;padding-bottom: 8px;text-align: center;font-size: 16px;color: #333;">
                        {{ pItem.title }}
                    </div>
                    <div style="width: 100%;padding: 0 16px;text-align: center;font-size: 14px;color: #333;word-break: break-all;white-space: pre-wrap;"
                        v-html="pItem.content">

                    </div>
                    <div
                        style="width: 100%;display: flex;height: 50px;border-top: 1px solid rgb(230,230,230);margin-top: 8px;">
                        <div v-if="pItem.showCancel" @click="async () => {
                            if (data.cannotClick) return
                            try {
                                await pItem.cancelCallBack()
                            } catch (error) {

                            }
                        }"
                            style="width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;color: dimgray;font-size:16px;cursor: pointer;">
                            {{ pItem.cancelText ? pItem.cancelText : '取消' }}
                        </div>
                        <div style="min-width: 1px ;height: 100%;background-color: rgb(230,230,230);">

                        </div>
                        <div @click="async () => {
                            if (data.cannotClick) return
                            try {
                                await pItem.okCallBack()
                            } catch (error) {

                            }
                        }"
                            style="width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;color: rgb(0,120,215);font-size:16px;cursor: pointer;">
                            {{ pItem.okText ? pItem.okText : '确定' }}
                        </div>
                    </div>
                </div>

            </flexBox>

        </div>
    </div>

    <div v-if="loading.data"
        style="width: 100%;height: 100%;position: absolute;left: 0;top: 0;z-index: 110;display: flex;align-items: center;justify-content: center;"
        :style="{
            pointerEvents: loading.mask ? 'fill' : 'none'
        }">
        <div style="min-width: 120px;height: 120px;background-color: rgba(0,0,0,0.8);border-radius: 8px;">
            <flexBox style="width: 100%;height: 100%;" flexDirection="column" gap="10px">
                <loadingCircle></loadingCircle>
                <span style="color: white;">{{ loading.title }}</span>
            </flexBox>
        </div>
    </div>

    <div v-if="toast.show"
        style="width: 100%;height: 100%;position: absolute;left: 0;top: 0;display: flex;align-items: center;justify-content: center;z-index: 110;"
        :style="{
            pointerEvents: toast.mask ? 'fill' : 'none'
        }">
        <div v-if="toast.icon"
            style="min-width: 120px;height: 120px;background-color: rgba(0,0,0,0.8);border-radius: 8px;padding: 8px 0;">
            <flexBox style="width: 100%;height: 100%;color: white;" flexDirection="column" gap="10px">
                <cIcon size="35px" :name="toast.icon"></cIcon>
                <span style="color: white;padding: 0 8px;word-break: break-all;white-space: wrap;">{{ toast.content
                }}</span>
            </flexBox>
        </div>
        <div v-if="!toast.icon"
            style="min-width: 120px;height: auto;background-color: rgba(0,0,0,0.8);border-radius: 8px;padding: 8px 0;">
            <flexBox style="width: 100%;height: 100%;color: white;" flexDirection="column" gap="10px">
                <span style="color: white;padding: 0 8px;word-break: break-all;white-space: wrap;">{{ toast.content
                }}</span>
            </flexBox>
        </div>
    </div>

</template>

<script setup>
import { ref, reactive, defineProps, computed, watch, onMounted, onBeforeUnmount } from 'vue'
import tool from '../tool'
import loadingCircle from '../components/loadingCircle.vue'
import flexBox from '../components/flexBox.vue'
import cIcon from '../components/cIcon.vue'
import controls from './controls'
import { toHandlers } from 'vue'

const loading = reactive({
    data: false,
    mask: false,
    title: '请稍候',
    show({ mask = false, title = '请稍候' }) {
        toast.handleHide()
        this.data = true
        this.mask = mask
        this.title = title ? title : '请稍候'
    },
    hide() {
        this.data = false
    }
})

const data = reactive({
    showBg: false,
    list: [],
    transition: true,
    scale: false,
    async delete() {
        let currentLength = this.list.length
        if (currentLength > 1) {
            this.transition = false
            await tool.wait(0.01)
            // this.showBg = false
            this.scale = true
            this.list = this.list.slice(0, currentLength - 1)
            await tool.wait(0.01)
            this.transition = true
            await tool.wait(0.01)
            this.showBg = true
            this.scale = false
            this.cannotClick = true
            await tool.wait(0.3)
            this.cannotClick = false
        } else {
            this.transition = true
            await tool.wait(0.01)
            this.showBg = false
            this.scale = true
            this.cannotClick = true
            await tool.wait(0.3)
            this.cannotClick = false
            this.list = this.list.slice(0, currentLength - 1)
        }
    },
    async add(obj) {
        let currentLength = this.list.length
        if (currentLength) {
            this.transition = false
            await tool.wait(0.01)
            this.scale = true
            // this.showBg = false
            await tool.wait(0.01)
            this.list.push(obj)
            this.transition = true
            await tool.wait(0.01)
            this.scale = false
            this.showBg = true
            this.cannotClick = true
            await tool.wait(0.3)
            this.cannotClick = false
        } else {
            this.transition = false
            await tool.wait(0.01)
            this.scale = true
            this.showBg = false
            await tool.wait(0.01)
            this.list.push(obj)
            this.transition = true
            await tool.wait(0.01)
            this.scale = false
            this.showBg = true
            this.cannotClick = true
            await tool.wait(0.3)
            this.cannotClick = false
        }
    },
    current() {
        return this.list[this.list.length - 1]
    },
    async deleteAll() {
        this.transition = false
        await tool.wait(0.01)
        this.showBg = false
        this.list = []
    },
    setUnlockSetter: null,
    setUnlock() {
        if (this.setUnlockSetter === null) {
            this.setUnlockSetter = true
        } else {
            try {
                this.setUnlockSetter()
            } catch (error) {

            }
        }
    },
    async waitUnlock() {
        if (this.setUnlockSetter === true) {
            this.setUnlockSetter = null
            return
        }
        return new Promise((resolve, reject) => {
            this.setUnlockSetter = () => {
                this.setUnlockSetter = null
                resolve()
            }
        })
    },
    async deleteByCreatedAt(createdAt) {
        if (this.current().createdAt == createdAt) {
            await this.delete()
        } else {
            this.list = this.list.filter(item => item.createdAt != createdAt)
        }
    },
    cannotClick: false
})

const status = ref(0)
tool.store.onChangeAndNotify('windowStatus', (e) => {
    status.value = e
})

const windowHeight = ref('')
tool.store.onChangeAndNotify('windowHeight', (e) => {
    windowHeight.value = e
})

const zoom = ref('')
tool.store.onChangeAndNotify('zoom', (e) => {
    zoom.value = e
})

const tasks = {
    list: [],
    running: false,
    async run() {
        if (!this.list.length) return
        if (this.running) return
        this.running = true
        while (1) {
            let current = this.getLeft()
            if (current === undefined) {
                this.running = false
                return
            }
            if (current.type == 'add') {
                await data.add(current.data)
            }
            if (current.type == 'delete') {
                await data.delete()
            }
            if (current.type == 'deleteAll') {
                await data.deleteAll()
            }
            if (current.type == 'wait') {
                await data.waitUnlock()
            }
            if (current.type == 'deleteByCreatedAt') {
                await data.deleteByCreatedAt(current.data.createdAt)
            }

            this.shift()
        }
    },
    shift() {
        this.list.shift()
    },
    getLeft() {
        return this.list[0]
    }
}

const toast = reactive({
    show: false,
    timer: null,
    mask: false,
    content: '',
    icon: '',
    handleShow({ content = '', icon = undefined, time = 500, mask = false }) {
        loading.hide()
        this.show = true
        this.mask = mask
        this.icon = icon
        this.content = content
        clearTimeout(this.timer)
        this.timer = setTimeout(() => {
            this.show = false
        }, time);
    },
    handleHide() {
        this.show = false
    }
})

onMounted(async () => {
    tool.store.onChange('controls', (e) => {
        if (['add', 'delete', 'deleteAll', 'wait', 'deleteByCreatedAt'].indexOf(e.type) + 1) {
            tasks.list.push(e)
            tasks.run()
        } else {
            if (e.type == 'showLoading') {
                loading.show({
                    mask: e.mask,
                    title: e.title
                })
            }
            if (e.type == 'hideLoading') {
                loading.hide()
            }
            if (e.type == 'showToast') {
                toast.handleShow({
                    content: e.content,
                    time: e.time,
                    icon: e.icon,
                    mask: e.mask
                })
            }
            if (e.type == 'hideToast') {
                toast.handleHide()
            }
        }

    })
})

</script>

<style scoped></style>